/**
 * @description 数组扁平化 - 推荐使用
 * @param {array} arr 需要扁平化的数组
 * @param {level} level 扁平层级. default: -, 默认拉平全部
 * @returns {array} 扁平后的数组
 * @example
 * ---------------------------
 * flatShallowArray([1, [2, 3], [4, 5, [6, 7]]])
 * // => [1, 2, 3, 4, 5, 6, 7]
 * --------------------------
 */
export function flattenArrayByFlat(arr: any[], level?: number): unknown[] {
  if (level) {
    return arr.flat(level)
  }
  return arr.flat(Number.POSITIVE_INFINITY)
}

/**
 * 数组扁平化
 * @param  {Array} target 要处理的数组
 * @param  {boolean} isDeep 是否深度扁平化. default: `false`
 * @param  {Array} output 扁平后的数组
 * @example
 * -----------------------------
 * // => flatten([1, 2, 8, [3, 4, [5, 6]], [7]], true) => [1, 2, 8, 3, 4, 5, 6, 7]
 * -----------------------------
 * // => flatten([1, 2, 8, [3, 4, [5, 6]], [7]], false) => [1, 2, 8, 3, 4, [5, 6], 7]
 */
export function flattenArray<T extends any[] = any[]>(target: T, isDeep = false, output?: T): T {
  output = output! || []
  let idx = output.length

  for (let i = 0, len = target.length; i < len; i += 1) {
    const value = target[i]
    if (Array.isArray(value)) {
      if (isDeep) {
        flattenArray(value, isDeep, output)
        idx = output.length
      } else {
        let j = 0
        const { length } = value
        while (j < length) output[idx++] = value[j++]
      }
    } else {
      output[idx++] = value
    }
  }

  return output
}

/**
 * @deprecated 请使用`flattenArrayByFlat` 或 `flattenArray`
 * @description 数组扁平化（所有层级）
 * @param {array} arr 需要扁平化的数组
 * @returns {array} 扁平后的数组Deep
 */
export function flatArrayDeep(arr: any[]): any[] {
  const result = [...arr].reduce((prev: any[], next: any[]) => prev.concat(Array.isArray(next) ? flatArrayInfinity(next) : next), [])
  return result
}

/**
 * @deprecated 请使用`flattenArrayByFlat` 或 `flattenArray`
 * @description 数组扁平化（浅度）
 * @param {array} arr 需要扁平化的数组
 * @returns {array} 扁平后的数组
 */
export function flatArrayShadow(arr: unknown[]): unknown[] {
  return (Function.apply.call([].concat, [], arr) as [])
}
